@L}5 _$% l0$)$$Hȱ$ UhL" `e$$%`$%`  R@P!( L(1   Y I`  d  Ld M * @  $ % CC$$)%1 Udߥ$9%: !0 S$% DD˙`  }J)Lr d M * @  $ % CC$$)%1 Udߥ$9%: !0 S$%} DD˙`  }J)Lr J  ((  p L ()   J}L= ( L 0q A    IB JC;? D W } LL  ` W )LA!  ߰")-݆ p" } $G@LL 08`Q")<2Q0 -G$Ș݆ UL# ; p8(()(0ʥ)NQ` }$GȘ݆LU )L ݆ L GȘ ݆LL )W>Z   HH)H }p h  hyhy D L> L JJ    ! LA*` BF }7'8  M HN H` 8 Z  \LdJJ!"! GFE@F (!L }EE !E^ ^ E E7EȩEdE/EȩE  D } .L }  ;F d  ;?F7F? ( .   Z D LL d } . D  L    p  E` , d)  D L) 0BM݊L݉} ML  N݆ L NLML [ TEqEHȱEqEh 0Gȹ G} HLL GɛL  LFREE SECTORS G) *Gȩ GȽG GȌ*jj >G} C8jJ3j2CD( C202C ԠBX` N 1? l LlD:RAMDISK}.COMLu L1 L ;LHL  T`  `1  ɐ     `TU  } L ? .  t`GBJ ~DEHI B V0dV!}QDEHI VF9 ,0 ,0 s0hhL  L` H hDHEh"}DEL8HI4 0 HI,0 0  9 .G VLO#},0 L4*IJ`llD1:AUTORUN.SYSNEED MEM.SAV TO LOAD THIS FILE.D1:MEM.SAV J y08 B|DEHI$} V0 0`B;DEL`?<0LV`@ʆ v s? F0Ξ05: [ BDEHI%} VY8 B V  @  /DE `E:D1:DUP.SYSERROR-SAVING USER MEMORY ON DISKTYPE Y TO &}STILL RUN DOS B;DE J  (` 9 V⪍ ઍ  -'}LLu ÝDEHILV 9 .l 9 .l  `` s$B BH(}I|DE V BLV nB,DE JLV B V BLVDEIʩ BꭝLu  } 3E:}DISK OPERATING SYSTEM II VERSION COPYRIGHT 1984 ATARI CORP.A. DISK DIRECTORY I. FORMAT DISKB. RUN CARTRIDG*}E J. DUPLICATE DISKC. COPY FILE K. BINARY SAVED. DELETE FILE(S) L. BINARY LOADE. RENAME FILE M. RUN AT ADDRES+}SF. LOCK FILE N. CREATE MEM.SAVG. UNLOCK FILE O. DUPLICATE FILEH. WRITE DOS FILES P. FORMAT SINGLEL !N',}#"&))9(&*)/h)''-&؆莟R'S  vL/ˢ L }Insert DOS 2.0s, type Y Λx -}DEfHI 1莏#q! @ y0ɛ8A0,' ȅ 1 1ild! 1L!NO SUCH ITEMSELECT.} ITEM OR FOR MENU! 0 .z:*{}.|{ 1 0 0JB 18L%|DL/}%DIRECTORY--SEARCH SPEC,LIST FILE?[# 0 0 &|D3" 1L!NOT A DISK FILEN !B 1L!E# 1 !BD0}ED:}:1BJ|DE 1DEBHI 1 h0ߢ 0.1}  0?詛 1 y0YЛ 1 ;#L" ;#L! BL1TYPE "Y" TO DELETE...DELETE FILE SPEC2}COPY--FROM, TO?OPTION NOT ALLOWED736 FREE SECTORS COPYING---D1:DIRECK.COMl# 0|D .L/%#3}##JB|DE 1BHID#E 1#0: B 1L!#͑### B 1#c$0SY4}S1}:## # # .#Ƚ# # 𩛙## 1,#PD#ELJ- <.BJD#E 5}1 1HH 0hh|DL%1}:̳# L% #D#EL% 1 0 . .0O% 1L!WILD CARDS NOT A6}LLOWED IN DESTINATION 0 <.|K}N 2 FORMAT. t* 5) 1L!`) 0NΞ 0 L1) 1 L!BAD LOAD FILELOAD FROM WHAT FILE?) 0 ?}0#B 1L!WHAT FILE TO LOCK?) 0 0$B 1L!WHAT FILE TO UNLOCK?DUP DISK-SOURCE,DEST DRIVES?TYPE "Y" IF OK TO US@}E PROGRAM AREACAUTION: A "Y" INVALIDATES MEM.SAV.FE! +L1   `*  70 2 2A} 0.* 1 y0 0)INSERT BOTH DISKS, TYPE RETURN^, 1 y038逍 N, 1L! ,B}C, t*  Lx+, 0 ^, 1 y0 , ,0,0 ,L+ ,I0 ,Vǭ0C}Ξ, 0 }, 1 y0C,ШC, 0K'!" H H 'h h Lx+!EF 5L1L!D,I,HhD}` NOT ENOUGH ROOMINSERT SOURCE DISK,TYPE RETURNINSERT DESTINATION DISK,TYPE RETURNE}`  `8 rL1`-* 1P* 1 y0Y`hhL!NAME OF FILE TO MOVE?- 0 0|DL% <.F},^ 1 70 0 .@L# .BJ 1  DEHIB V L1 ,} 1 70,L.  G}JB|,#P#DE 1 HI BDEHHII 1 B 1 ,^ 1 70,0La- B V,#PH},^ 1 70 0L#L!-* 1P* 1 y0Yj383}mm ݭI}}`8}``|* ? ɛ,`|:-)| / 1L!`DESTINATION CANT BE DOJ}S.SYS0 0H{ 24Δ 28/L!/) 2 Π 2 0 ξK}hAΞB,0 J 1 BDEHI,HÝDE 1HIHIDELSAVE-GIVE L}FILE,START,END(,INIT,RUN)O S0 1`BDEPHI V` S0H 1 L!M}0 0 1L~0`PLEASE TYPE 1 LETTER,0`hhL! 70 1L0L<1 ,;ɛ7,"ɛ:ݦ1ݥN}A"D|ݤD|ȩ:|ȩ|ɛ,,(/+.ީ1 1,ɛ`轤{NAMEO} TOO LONG B VL!` L1I H1EΝDL1|mDiE` V0`8d/8 i:222 1 LP}!ERROR- 138ɛ+,' 20*.. өr2 1``2TOO MANY DIGITSINVALID HEXAQ}DECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 THRU D8uR} ECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 THRU D8u This is a redistribution of theAction! Kermit program. All I'vedone is repackage everything in anARChive file. I haveT}n't tested it,as I don't have Action!.n! Kermit program. All I'vedone is repackage everything in anARChive file. I have(;D:KCOM1030.ACT;All the communications stuff:;;Opening, closing and dialing for;the ATARI 1030 modem;; KERMIT protocol V}; for Atari Home Computers; version 1.1; (C) 1983 John Howard Palevich; to be distributed free of charge;;Started NOVEMB W}ER 5, 1983;Print a string which will identify,;to the user, what hardware this;COM file supportsPROC MODEMINIT() PRIN X}TE("for the Atari 1030 modem") RETURN;Return number of character in the;input bufferCARD FUNC NCIB() BYTE INCNT = $4 Y}00 RETURN(INCNT);Put a character out the modemPROC PUTR(BYTE DATA) PUTD(2, DATA) RETURN;Put out a byte as a modem Z} commandPROC PUTCMD(BYTE CMD) BYTE CMCMD = $0007 CMCMD = $FF PUTD(2, 27) PUTD(2, CMD) CMCMD = 0 RETURN;Tempor [}arily Suspend Communications;so that file I/O can take placePROC StopR() PUTCMD('Z) RETURN;Close down the modem chan \}nelPROC CloseR() PUTCMD('Y) CLOSE(2) RETURN;Initialize communicationsBYTE FUNC OpenR() STRING fname = "##:" B ]}YTE T Close(2) fname(1) = 'T fname(2) = '1 t = 12 Open(2, fname, t, 0) T = MSTATUS(2) IF T >= 128 THEN PR ^}INTF("Can't open %S, error %B%E", fname, T) CLOSE(2) RETURN(T) FI RETURN(0)PROC StartR() PUTCMD('Y) ;R _}esume operation PUTCMD('A) PUTR($20) PUTR('?) ;No Translation PUTCMD('C) PUTR(PARITY) RETURN;SubEQ(S, I, `}SS);; Check if SS is = S(I..I+Len(SS)-1)BYTE FUNC SUBEQ(STRING S BYTE I STRING SS) INT J IF S(0)-I+1 < SS(0) THEN RET a}URN(0) FI FOR J = 1 TO SS(0) DO IF S(I+J-1) <> SS(J) THEN RETURN(0) FI OD RETURN(1);Dial the number b}in string P;return 0 if failure, 1 if OKBYTE FUNC AutoDial(STRING P) BYTE I, NN, C, DVSTAT1 = $2EB NN = P(0) ;LEN c}GTH OF STRING ;This modem ignores baud rate FOR C = 1 TO NN DO IF P(C) = '# THEN DO C ==+ 1 U d}NTIL C > NN OR P(C) > 32 OD EXIT FI OD IF C > NN THEN PRINTE("No phone number in this entry! e}") RETURN(0) FI PRINTE("Dialing...press any key to abort") ERRORNUM = 0 STARTR() IF dial = 0 THEN PUTCMD( f}'N) ELSE PUTCMD('O) FI PUTCMD('K) FOR I = C TO NN DO PutR(P(I)) OD PutR($9B) ;Wait for carrier WH g}ILE CH = $FF DO MDEVSTAT(2) IF (DVSTAT1 & $80) <> 0 THEN RETURN(1) FI OD PRINTE("User abort") PUTCMD( h}'M) ;Go on-hook STOPR() RETURN(0);Hang up the phone linePROC HANGUP() STARTR() PUTCMD('M) ;Go on-hook STOPR() i} RETURN ; --- END OF D:KCOM1030.ACT ---g up the phone linePROC HANGUP() STARTR() PUTCMD('M) ;Go on-hook STOPR() +;D:KCOM850.ACT;All the communications stuff:;; Opening, closing and; DIALING; (for the DC-Hayes Smartmodem); KERMIT prok}tocol; for Atari Home Computers; version 1.1; (C) 1983 John Howard Palevich; to be distributed free of charge;;Started l}NOVEMBER 5, 1983PROC MODEMINIT() PRINTE("for the Atari 850 and the") PRINTE("DC-Hayes Smartmodem") RETURNCARD FUNC m}NCIB() CARD NC = 747, INCNT = $400 BYTE I MDEVSTAT(2) I = MSTATUS(2) IF I >= 128 THEN PRINTF("R: device n}error: %D%E", I) RETURN(0) FI RETURN(NC) PROC PUTR(BYTE DATA) PUTD(2, DATA) RETURN;Temporarily Suspendo} Communications I/OPROC StopR() Close(2) RETURNPROC CloseR() CLOSE(2) RETURNBYTE FUNC OpenR() STRING fname = p}"##:" BYTE T Close(2) fname(1) = 'R fname(2) = dnum + '0 t = 13 Open(2, fname, t, 0) T = MSTATUS(2) IF T >= 1q}28 THEN PRINTF("Can't open %S, error %B%E", fname, T) CLOSE(2) RETURN(T) FI CIOV(2, 34, 0, 0, 192+48r}, 0) CIOV(2, 38, 0, 0, 32+PARITY*5, 0) CIOV(2, 36, 0, 0, 8+baud, 0) CIOV(2, 40, 0, 0, 0, 0) RETURN(0)PROC StartR()s} OpenR() RETURN;SubEQ(S, I, SS);; Check if SS is = S(I..I+Len(SS)-1)BYTE FUNC SUBEQ(STRING S BYTE I STRING SS) t} INT J IF S(0)-I+1 < SS(0) THEN RETURN(0) FI FOR J = 1 TO SS(0) DO IF S(I+J-1) <> SS(J) THEN RETURN(0) FIu} OD RETURN(1);GetMack() - wait for reply from SMPROC GetMack() BYTE A, S IF ERRORNUM >= 128 THEN RETURN FI S =v} 0 DO IF CH <> $FF THEN ERRORNUM = $FF RETURN FI IF NCIB() > 0 THEN A = GETD(2) IF DEBUw}G = 1 THEN PUT(27) PUT(A) FI IF S = 0 THEN IF A >= 32 THEN S = 1 FI x} ELSE IF A = 10 THEN ;End of reply RETURN FI FI FI OD ;PutMatch(c) - put a characty}er out; to R:, wait for a matching character; or user's abortPROC PutMatch(BYTE c) BYTE A PUTD(2, C) IF ERRORNUM >=z} 128 THEN RETURN FI DO IF CH <> $FF THEN ERRORNUM = $FF RETURN FI IF NCIB() > 0 THEN A = GE{}TD(2) IF DEBUG = 1 THEN PUT(27) PUT(A) FI IF A = C THEN RETURN FI FI OD|};Dial the number in string P....BYTE FUNC AUTODIAL(STRING P) BYTE I, C, NN NN = P(0) ;LENGTH OF STRING ;See}} if Baud Rate Specified FOR C = 1 TO NN DO IF P(C) = '( THEN IF SUBEQ(P,C,"(300)") = 1 THEN BAUD = 0 ~} ELSEIF SUBEQ(P,C,"(1200)") = 1 THEN BAUD = 2 FI EXIT FI OD FOR C = 1 TO NN DO IF} P(C) = '# THEN DO C ==+ 1 UNTIL C > NN OR P(C) > 32 OD EXIT FI OD IF C > NN } THEN PRINTE("No phone number in this entry!") RETURN(0) FI PRINTE("Dialing...press any key to abort") ERRORNU}M = 0 STARTR() PutMatch(13) ;Establish baud Rate PutMatch('A) PutMatch('T) PutMatch(13) GetMack() ;Swallow Reply} PutMatch('A) PutMatch('T) PutMatch(' ) PutMatch('D) IF dial = 0 THEN PutMatch('P) ELSE PutMatch('T) FI} FOR I = C TO P(0) DO PutMatch(P(I)) OD PutMatch(13) DO IF ERRORNUM >= 128 OR CH <> $FF THEN PRI}NTE("User Aborted") PUTD(2, 13) ;to get out of wait-for-carrier mode I = RTCLOCK+10 WHILE RTCLOCK <> I DO O}D ;Drain STOPR() RETURN(0) FI IF NCIB() > 0 THEN C = GetD(2) IF DEBUG = 1 THEN PUT(27}) PUT(C) FI IF C = 'C OR C = '1 THEN ;Connected STOPR() RETURN(1) ELSEIF C >= 32 TH}EN PrintF("Unexpected result '%C'%E", C) STOPR() RETURN(0) FI FI OD;CAUSE THE SMARTMODE}M TO HANG UPPROC HANGUP() BYTE B STARTR() ;As per page 9-2 of the Smart- ;modem manual. Basicly, the ;escape seq}uence has to be pre- ;ceded by at least one character, ;and we can't count on the user ;having typed one, so we type on}e ;ourselves. PUTR('+) WAIT(100) PUTR('+) PUTR('+) PUTR('+) WAIT(200) ;Flush buffer WHILE NCIB() > 0 DO } B = GETD(2) IF DEBUG = 1 THEN PUT(27) PUT(B) FI OD ERRORNUM = 0 PutMatch(13) ;Establish baud Rate} PutMatch('A) PutMatch('T) PutMatch(13) GetMack() ;Swallow Reply PUTMATCH('A) PUTMATCH('T) PUTMATCH(32) PUTMA}TCH('H) PUTMATCH('0) PUTMATCH(13) GETMACK() STOPR() RETURN; --- END OF D:KCOM850.ACT ---) PUTMATCH(32) PUTMAe;D:KDIAL.ACT;Auto-Dial and phone number editor; (for the DC-Hayes Smartmodem); KERMIT protocol; for Atari Home Computers}; version 1.1; (C) 1983 John Howard Palevich; to be distributed free of charge;;Started NOVEMBER 5, 1983MODULE STRING }PNFILE = "D:KERMIT.PNS" DEFINE NUMWID = "38";SubEQ(S, I, SS);; Check if SS is = S(I..I+Len(SS)-1)BYTE FUNC SUBEQ(STRI}NG S BYTE I STRING SS) INT J IF S(0)-I+1 < SS(0) THEN RETURN(0) FI FOR J = 1 TO SS(0) DO IF S(I+J-1) <> SS(J) THEN} RETURN(0) FI OD RETURN(1);GetMack() - wait for reply from SMPROC GetMack() BYTE A, S IF ERRORNUM >= 12}8 THEN RETURN FI S = 0 DO IF CH <> $FF THEN ERRORNUM = $FF RETURN FI IF NCIB() > 0 THEN A} = GETD(2) IF DEBUG = 1 THEN PUT(27) PUT(A) FI IF S = 0 THEN IF A >= 32 THEN } S = 1 FI ELSE IF A = 10 THEN ;End of reply RETURN FI FI FI OD ;Put}Match(c) - put a character out; to R:, wait for a matching character; or user's abortPROC PutMatch(BYTE c) BYTE A PUT}D(2, C) IF ERRORNUM >= 128 THEN RETURN FI DO IF CH <> $FF THEN ERRORNUM = $FF RETURN FI IF NCIB}() > 0 THEN A = GETD(2) IF DEBUG = 1 THEN PUT(27) PUT(A) FI IF A = C THEN RET}URN FI FI OD;Restore Phone Number BufferPROC RESTNUMS() BYTE I, J Close(3) ERRORNUM = 0 OPEN(3, PNFI}LE, 4, 0) IF ERRORNUM < 128 THEN FOR I = 0 TO 19 DO ERRORNUM = 0 InputMD(3,SBUF+I*NUMWID, 37) IF ERRO}RNUM >= 128 THEN EXIT FI OD ELSE I = 0 ;Couldn't find file FI CLOSE(3) FOR J = I TO 19 DO } SBUF(NUMWID*J) = 0 OD RETURN;Display the editor screenPROC DispES() BYTE I ;Display Screen CRSINH = 1 PUT(}125) FOR I = 0 TO 19 DO Put(32) PRINTE(SBUF+NUMWID*I) OD PUTE() PrintE("Use arrows, then RETURN to dial,")} PrintE("or ESC to quit. ^S Saves") PRINT("SPACE modifies, ^R Restores") Position(LMARGN, 0) Put($1F) CRSINH = 0 }Put($1E) RETURN;Auto-Dial a number, return 1 if;successful, 0 if failure;; Also has provisions for editing; phone num}bers.BYTE FUNC AutoDial() BYTE I, NN, C, CY BYTE POINTER P RESTNUMS() DISPES() CY = 0 ;Edit/Select Loop }DO CRSINH = 1 POSITION(LMARGN, CY) PUT(27) PUT($1F) C = GetD(1) IF C = 32 THEN ;User wants to cha}nge this line POSITION(LMARGN,CY) CRSINH = 0 PUT('?) InputMD(0,SBUF+CY*NUMWID, 37) DISPES() } ELSEIF C = 27 THEN Position(LMARGN, 23) CRSINH = 0 PUT($9C) PrintE("Not Dialing") RETURN(0)} ELSEIF (C = $1C OR C = '-) AND CY > 0 THEN PUT($7E) ;Erase the arrow CY ==- 1 ELSEIF (C = $1D OR C} = '=) AND CY < 19 THEN PUT($7E) ;Erase the arrow CY ==+ 1 ELSEIF C = 'S-'@ THEN ;^S OPEN(3, PNF}ILE, 8, 0) FOR I = 0 TO 19 DO P = SBUF+I*NUMWID IF P(0) > 0 THEN PRINTDE(3, P) FI } OD CLOSE(3) RESTNUMS() DISPES() ;Just to inform user CY = 0 ELSEIF C = 'R-'@ THEN ;^R R}ESTNUMS() DISPES() CY = 0 ELSEIF C = $9B THEN ;RETURN EXIT FI OD ;Dial the chosen number C}RSINH = 0 PUT(125) P = SBUF+CY*NUMWID PrintE(P) NN = P(0) ;LENGTH OF STRING ;See if Baud Rate Specified FOR }C = 1 TO NN DO IF P(C) = '( THEN IF SUBEQ(P,C,"(300)") = 1 THEN BAUD = 0 ELSEIF SUBEQ(P,C,"(1200)")} = 1 THEN BAUD = 2 FI EXIT FI OD FOR C = 1 TO NN DO IF P(C) = '# THEN DO } C ==+ 1 UNTIL C > NN OR P(C) > 32 OD EXIT FI OD IF C > NN THEN PRINTE("No phone num}ber in this entry!") RETURN(0) FI PRINTE("Dialing...press any key to abort") ERRORNUM = 0 STARTR() PutMatch(13}) ;Establish baud Rate PutMatch('A) PutMatch('T) PutMatch(13) GetMack() ;Swallow Reply PutMatch('A) PutMatch('T)} PutMatch(' ) FOR I = C TO NN DO PutMatch(P(I)) OD PutMatch(13) DO IF ERRORNUM >= 128 OR CH <> $FF T}HEN PRINTE("User Aborted") PUTD(2, 13) ;to get out of wait-for-carrier mode I = RTCLOCK+10 WHILE RTCL}OCK <> I DO OD ;Drain StopR() RETURN(0) FI IF NCIB() > 0 THEN C = GetD(2) IF DEBUG = 1 THEN } PUT(27) PUT(C) FI IF C = 'C OR C = '1 THEN ;Connected STOPR() RETURN(1) ELSE}IF C >= 32 THEN PrintF("Unexpected result '%C'%E", C) STOPR() RETURN(0) FI FI OD; --- E}ND OF D:KDIAL.ACT --- PrintF("Unexpected result '%C'%E", C) STOPR() RETURN(0) FI FI OD; --- E;D:KERMIT.ACT;; KERMIT protocol; for Atari Home Computers; version 1.2; (C) 1984 John Howard Palevich}; to be distributed free of charge;;Started September 24, 1983;Start code above T: and/or R:;by compiling while those d}evices;are in RAM. There ought to be a;better way!MODULEDEFINE MAXPACK = "94"BYTE ARRAY RECPKT(MAXPACK), PACKET(}MAXPACK), FILNAM, SBUF(2050)DEFINE EOF = "-1", SOH = "1", CR = "13", MAXTRY = "5", MYQUOTE = "'#", TRUE = }"1", FALSE = "0"BYTE LMARGN = $52,;OS LEFT MARGIN CH = 764, ;OS CH VARIABLE RTCLOCK = 20,;OS CLOCK IN JIFFYS C}RSINH = $2F0, ;OS CURSOR INHIBIT FLAG BACKS, ;CHAR TO SEND FOR BACK S baud, ;baud rate variable dial, } ;nz for tone dialing DISKN, ;DEFAULT DISK DNUM, ;port num localecho, ;local echo flag PARITY, };communication parity ERRORNUM, ;ERROR NUMBER debug, ;debugging flag STATE, PADCHAR, EOL, QUOTEINT }SIZE, N, RPSIZ, SPSIZ, PAD, TIMINT, NUMTRY, OLDTRY, FD, REMFD, IMAGE, HOSTINCLUDE "D:KIO.ACT"; This} is where KCOM#.ACT is;included. Include the KCOM file;which matches the comunications;device and/or modem you wish to us}e.;; For an 850 and a Hayes SmartModem,;include KCOM850.ACT;; For the ATARI 1050,;include KCOM1050.ACT;; For any othe}r set of devices, write;your own KCOM functions, and include;that file here.INCLUDE "D:KCOM850.ACT"INCLUDE "D:KFUNC.ACT}"INCLUDE "D:KPRO.ACT"INCLUDE "D:KTTY.ACT"INCLUDE "D:KMENU.ACT"; --- END OF D:KERMIT.ACT ---0.ACT"INCLUDE "D:KFUNC.ACTaHow to install Kermit on your ATARIhome computer.RAM: 48K, or more RAMPeripherals: At least one disk drive } ATARI 850 & a modem, or ATARI 1030, or other communications device1) Format a diskette and w}rite a copyof DOS onto it.2) Write the AUTORUN.SYS file for thetype of modem that you are going touse. If you are usin}g an 850, writethe AUTORUN.SYS file that came with theDOS II Master Diskette.3) Write all the K*.* files onto thedisket}te.4) Insert an ACTION! cartridge intoyour ATARI computer, turn on your 850(or 1030, or whatever) and power cycleyour A}TARI computer. After the DOSboots you should see the ACTION! editorscreen.5) Read in and edit the file"KERMIT.ACT". C}hange the line near theend of the file from "KCOM850.ACT" towhichever device you wish to use.Write out the "KERMIT.ACT" fi}le whenyou are done. If you are trying tosupport a new modem type, create a newKCOM file and use its name here....6) C}lear the editor buffer and go tothe ACTION! monitor. TypeR "KERMIT.ACT"to compile and run the Kermit program.That's it.} Here are some commonly askedquestions, with some off-the-cuffanswers:Q: Why do I need an ACTION! cartridgeto run Kerm}it?A: The people who developed ACTION!have not yet provided a way of runningtheir program without the ACTION! cart.Q: } Why do I have to re-compile theprogram every time I want to use it?A: DOS II's menu program destroysthe R: and T: devic}e drivers, so youcan't use the "L" menu option to runa pre-compiled ACTION program thatdepends on the R: or T: drivers.I}f you are clever, you can append theACTION! object code to the AUTORUN.SYSfile to generate an auto-bootingversion of KERMI}T.If you have OS/A+, you can, indeed,save the compiled version of Kermit andexecute it from the command line. Justmake }sure that you have loaded adevice driver first!Jack Palevich Kermit andexecute it from the command line. Justmake DSU-Score(300)#4153221570SU-Score(1200)#4154970061Jack Palevich Kermit andexecute it from the command line. Justmake 3;D:KFUNC.ACT; Utility functions for Kermit; (C) 1983 John Howard Palevich; to be distributed free of charge;;Started Sep$}tember 24, 1983MODULECARD ARRAY bauds = [300 600 1200 1800 2400 4800 9600]PROC $}SHOWBUF(STRING BUF, INT LEN) INT I FOR I = 0 TO LEN-1 DO PUT(27) PUT(BUF(I)) OD RETURNPROC MERROR(BYTE A,X,$}Y) IF debug = 1 THEN PRINTF("ERROR %B%E", y) IF Y = 128 THEN CLOSE(2) CLOSE(3) CLOSE(1) BRE$}AK() FI FI ERRORNUM = Y RETURNCARD FUNC DecodeBaud(BYTE b) STRING buf(6) STRC(bauds(b), buf) RETURN(buf)C$}ARD FUNC DecodeFlag(BYTE f) IF f = 0 THEN RETURN("off") ELSE RETURN("on") FIBYTE FUNC IsAlpha(BYTE c) IF (c$} >= 'a AND c <= 'z) OR (c >= 'A AND c <= 'Z) THEN RETURN(1) ELSE RETURN(0) FIBYTE FUNC ToUpper(BYTE c) $} IF c >= 'a AND c <= 'z THEN RETURN(c - 32) ELSE RETURN(c) FI;SPack();; Send a PacketPROC SPack(BYTE TY $} INT NUM, LEN STRING DATA) INT I, BUFP BYTE CHKSUM STRING BUFFER(100) IF DEBUG = 1 THEN PRINTF$}("SPack('%C,%D,%D,", TY, NUM, LEN) PUT('") SHOWBUF(DATA, LEN) PRINTF("%C)%E", '") ELSE PUT('.) FI$} FOR I = 1 TO PAD DO PUTD(2, PADCHAR) OD BUFFER(0) = SOH BUFFER(1) = 32 + LEN+3 BUFFER(2) = 32 + NUM BUFFER$}(3) = TY CHKSUM = BUFFER(1)+BUFFER(2) +BUFFER(3) FOR I = 0 TO LEN-1 DO BUFFER(I+4) = DATA(I) CHKSUM ==+ D$}ATA(I) OD CHKSUM = (CHKSUM + ((CHKSUM & 192) RSH 6)) & 63 BUFFER(LEN+4) = 32 + CHKSUM BUFFER(LEN+5) = EOL CIOV$}(2, 11, BUFFER, LEN+6, -1, -1) RETURN;GetRT; Get a byte from R: with timeout; and user-abortBYTE FUNC GetRT(BYTE POIN$}TER B) CHAR FSC = 19, TIMER TIMER = FSC+3 WHILE NCIB() = 0 DO IF FSC = TIMER THEN IF DEBUG = 1 THEN ;say tim$}eout PRINTE("(Timeout)") FI RETURN(0) ELSEIF CH <> $FF THEN ;User abort RETURN(0) FI OD $} B^ = GETD(2) RETURN(1); RPack();; Read a PacketINT FUNC RPack(INT POINTER LEN, NUM STRING DATA) INT I, $}DONE CHAR CHKSUM, T, UT, TY IF DEBUG = 1 THEN PRINT("RPack") FI DO IF GETRT(@T) = 0 THEN RETURN(0) $} FI IF DEBUG = 1 AND T <> SOH THEN PUT(27) PUT(T) FI UNTIL T = SOH OD DONE = FALSE WHILE DON$}E = FALSE DO IF GETRT(@T) = 0 THEN RETURN(0) FI IF IMAGE = FALSE THEN T ==& 127 FI IF T$} <> SOH THEN ;GOT LEN CHKSUM = T LEN^ = T-3-32 IF GETRT(@T) = 0 THEN RETURN(0) FI IF$} IMAGE = FALSE THEN T ==& 127 FI IF T <> SOH THEN ;GOT NUM CHKSUM ==+ T NUM^ = T - $}32 IF GETRT(@T) = 0 THEN RETURN(0) FI IF IMAGE = FALSE THEN T ==& 127 FI IF T <> S$}OH THEN CHKSUM ==+ T TY = T FOR I = 0 TO LEN^-1 DO IF GETRT(@T) = 0 THEN $} RETURN(0) FI IF IMAGE = FALSE THEN T ==& 127 FI IF T = SOH THEN EXIT FI $}CHKSUM ==+ T DATA(I) = T OD IF T <> SOH THEN IF GETRT(@T) = 0 THEN $} RETURN(0) FI IF IMAGE <> TRUE THEN T ==& 127 FI IF T <> SOH THEN DONE = TR$}UE FI FI FI FI FI OD CHKSUM = (CHKSUM + ((CHKSUM & 192) RSH 6)) & 63 UT = $}T - 32 IF CHKSUM <> UT THEN IF DEBUG = 1 THEN PRINTF("(Bad checksum: %D <> %D)%E", CHKSUM, UT) FI $} RETURN(FALSE) FI IF DEBUG = 1 THEN ;give type PRINTF("('%C%C,%D,%D,%C", 27, TY, NUM^, LEN^, '") SHOWBUF(DA$}TA, LEN^) PRINTF("%C)%E", '") FI IF TY = 'E THEN PRINT("Error: ") SHOWBUF(DATA, LEN^) PUTE() FI RETUR$}N(TY);BuFill;;Get a bufferful of data from the;file that's being sent. Only;control-quoting is done; 8-bit &;repeat $}count prefixes arn't handledINT FUNC BuFill(STRING BUFFER) INT I BYTE T,T7 STOPR() I = 0 DO T = GETD(3) I$}F MStatus(3) >= 128 THEN IF DEBUG = 1 THEN PRINTE("End-of-file") FI EXIT FI IF IMAGE = TRUE$} THEN T7 = T & 127 IF T7 < 32 OR T7 = 127 OR T7 = QUOTE THEN BUFFER(I) = QUOTE I ==$}+ 1 IF T7 <> QUOTE THEN T ==! 64 FI FI ELSE IF T <> 155 THEN T ==& 127 FI IF $}T < 32 OR T = 127 OR T = QUOTE OR T = 155 THEN IF T = 155 THEN BUFFER(I) = QUOTE BU$}FFER(I+1) = 13 ! 64 I ==+ 2 T = 10 FI BUFFER(I) = QUOTE I ==+ 1 IF T <> Q$}UOTE THEN T==! 64 FI FI FI BUFFER(I) = T I ==+ 1 IF I >= SPSIZ-8 THEN STARTR() RETURN(I) $} FI OD STARTR() IF I = 0 THEN RETURN(EOF) ELSE RETURN(I) FI;BufEmp;;Get data from an incomming packe$}t;into a file.PROC BufEmp(STRING BUFFER INT LEN) INT I BYTE T STOPR() FOR I = 0 TO LEN-1 DO $} T = BUFFER(I) IF T = MYQUOTE THEN I ==+ 1 T = BUFFER(I) IF (T & 127) <> MYQUOTE THEN $} T ==! 64 FI FI IF IMAGE = TRUE THEN PUTD(3, T) ELSEIF T = CR THEN PUTD(3, 155) ELSEIF T <$}> 10 THEN PUTD(3, T) FI OD STARTR() RETURN;SPar();;Fill the data array with my;send-init parametersPRO$}C SPar(STRING DATA) DATA(0) = 32 + MAXPACK DATA(1) = 32 + 5 DATA(2) = 32 + 0 DATA(3) = 64 ! 0 DATA(4) = 32 + 13 D%}ATA(5) = MYQUOTE RETURN;RPar();;Get the other host's send-init;parametersPROC RPAR(STRING DATA) SPSIZ = DATA(0) - %}32 TIMINT = DATA(1) - 32 PAD = DATA(2) - 32 PADCHAR = DATA(3) ! 64 EOL = DATA(4) - 32 QUOTE = DATA(5) RETURN; -%}-- END OF D:KFUNC.ACT --- PAD = DATA(2) - 32 PADCHAR = DATA(3) ! 64 EOL = DATA(4) - 32 QUOTE = DATA(5) RETURN; -$;D:KIO.ACT ; I/O routines for kermit; (C) 1983 John Howard PalevichDEFINE STRING = "BYTE ARRAY"STRING iocbCARD filen)}umberSTRING dname(20), fname(20);WAIT T 60THS OF A SECONDPROC WAIT(INT T) BYTE I WHILE T > 255 DO I = RTCLOCK)}-1 WHILE I <> RTCLOCK DO OD T ==- 255 OD I = RTCLOCK + T WHILE I <> RTCLOCK DO OD RETURNPROC STRCPY(STRING )}A, B) CARD I FOR I = 1 TO B(0) DO A(I) = B(I) OD A(0) = B(0) RETURNBYTE FUNC MStatus(BYTE ch) iocb = $340 + c)}h LSH 4 RETURN (iocb(3))PROC CIO=$E456(BYTE a, x)PROC CIOV(BYTE ch, cmd CARD adr, len INT ax1, ax2))} iocb = $340 + ch LSH 4 iocb(2) = cmd iocb(4) = adr iocb(5) = adr RSH 8 iocb(8) = len iocb(9) = len RSH 8 IF ) }ax1 >= 0 THEN iocb(10) = ax1 FI IF ax2 >= 0 THEN iocb(11) = ax2 FI CIO(0, CH * 16) RETURN;Do a Get Statu) }s CommandBYTE FUNC MDevStat(BYTE ch STRING adr) CIOV( ch, $0D, adr + 1, adr(0), -1, -1) RETUR) }N(iocb(3)); -- file locking, unlocking, etc.; -- directory hacking functions;Returns 0 if EOF, else the file nameCARD F) }UNC GetNext(CHAR ch) INT I, J STRING DSPEC(20) Close(ch) Open(ch, dname, 6, 0) IF mstatus(ch) >= 128 THEN RET) }URN(0) FI FOR i = 0 TO filenumber DO INPUTMD(ch, DSPEC, 20) IF mstatus(ch) >= 128 THEN Close(ch) R)}ETURN(0) FI OD IF DSPEC(0) <> 17 THEN RETURN(0) FI filenumber ==+ 1 Close(ch) ;Convert dspec into file name I)} = 1 DO FNAME(I) = DNAME(I) I ==+ 1 UNTIL DNAME(I-1) = ': OD J = 3 DO FNAME(I) = DSPEC(J) I ==)}+ 1 J ==+ 1 UNTIL J > 10 OR DSPEC(J) = 32 OD FNAME(I) = '. I ==+ 1 J = 11 WHILE J <= 13 AND DSPEC(J) )}<> 32 DO FNAME(I) = DSPEC(J) I ==+ 1 J ==+ 1 OD FNAME(0) = I-1 RETURN(fname);Get the first nameCARD )}FUNC GetFirst(BYTE ch STRING name) STRCPY(dname, NAME) filenumber = 0 RETURN(GetNext(ch));FIND CH)}AR C IN STRING ABYTE FUNC FindC(STRING a BYTE c) CARD i,l l = a(0) FOR i = 1 TO l DO IF a(i) = c THEN)} EXIT FI OD RETURN(i);Normalize a file name string to Dn:<0..8>.<0..3>;where n is the value of diskn;name sh)}ould be at least 3+8+1+3+2=17 bytes long;returns 0 if not a valid nameBYTE FUNC Normalize(STRING name) CARD i, len BYT)}E C len = name(0) IF len = 0 THEN RETURN(0) FI;first, check if (): i = FindC(name,':) IF i)} > len THEN FOR i = 1 TO len DO name(len-i+4) = name(len-i+1) OD name(1) = 'D name(2) = '0 + DISKN )}name(3) = ': len ==+ 3 FI;fixup length name(0) = len;and convert to upper case FOR i = 1 TO len DO c = nam)}e(i) IF c >= 'a AND c <= 'z THEN name(i) = c - 32 FI OD RETURN(1)BYTE FUNC INSET(BYTE C STRING S) CARD)} I FOR I = 1 TO S(0) DO IF C = S(I) THEN RETURN(I) FI OD RETURN(0); --- END OF D:KIO.ACTG S) CARD(r;D:KMAIN.ACT; Main functions of Kermit programMODULE STRING PARAMFILE = "D:KERMIT.OPT";Execute a DOS-type commandPRO-}C DODOS(BYTE CMD STRING FSPEC) STRING FMSCOM = [0 $21 $23 $24 $FE] BYTE I, CNF IF FSPEC(0) = 0 AND CMD <> '-}A THEN RETURN FI IF CMD = 'A THEN ;DIRECTORY IF FSPEC(0) = 0 THEN STRCPY(FSPEC, "D:*.*") FI N-}ORMALIZE(FSPEC) CLOSE(6) ERRORNUM = 0 OPEN(6, FSPEC, 6, 0) DO INPUTMD(6, FILNAM, 20) IF ERRORNUM -}>= 128 THEN EXIT FI PRINTE(FILNAM) IF FILNAM(1) >= '0 AND FILNAM(1) <= '9 THEN EXIT FI OD - }CLOSE(6) ELSE ;ALL OTHER COMMANDS NORMALIZE(FSPEC) I = INSET(CMD, "DFGI") IF I = 0 THEN RETURN FI -!}IF CMD = 'I THEN PRINTF("Type 'Y' to format %S%E", FSPEC) CNF = GetD(1) IF TOUPPER(CNF) <> 'Y -"} THEN PRINTF("Aborted%E") RETURN ELSE PRINT("Formatting. . .") FI FI ERRORNUM-#} = 0 XIO(6, 0, FMSCOM(I), 0, 0, FSPEC) IF ERRORNUM >= 128 THEN PRINTF("Disk I/O error %B%E", ERRORN-$}UM) FI FI RETURN PROC MICRODOS() BYTE cmd STRING fspec(21) PUT(125) DO PRINTE("Micro-DOS:") PRIN-%}TE(" A - Disk Directory") PRINTE(" D - Delete File") PRINTE(" F - Lock File") PRINTE(" G - Unlock File") PRIN-&}TE(" I - Format Diskette") PRINTE(" Q - Quit (back to main menu)") PRINTF("%ECommand -> ") DO cmd = GetD(1)-'} cmd = ToUpper(cmd) UNTIL INSET(CMD, "ADFGIQ") > 0 OD PUT(CMD) IF cmd = 'Q THEN PUTE()-(} RETURN FI PRINTF("%EFile spec -> ") InputMD(0, fspec, 20) DoDos(cmd, fspec) OD; SAVE PARAMETERSP-)}ROC SaveParams() ERRORNUM = 0 OPEN(3, PARAMFILE, 8, 0) IF ERRORNUM < 128 THEN ;Can write PUTD(3, BACKS) -*} PUTD(3, BAUD) PUTD(3, DEBUG) PUTD(3, IMAGE) PUTD(3, LOCALECHO) PUTD(3, LMARGN) PUTD(3, PARITY) PUT-+}D(3, DEVICE) FI CLOSE(3) RETURN;RESTORE PARAMETERSPROC RestoreParams() CLOSE(3) ERRORNUM = 0 OPEN(3, PARAMFI-,}LE, 4, 0) IF ERRORNUM >= 128 THEN ;Defaults PRINTF("Couldn't open %S; error %D%E", PARAMFILE, ERRORNUM)--} BACKS = 127 ;RUB OUT baud = 0 ;300 baud debug = 0 ;debug off IMAGE = 0 -.} ;TEXT localecho = 0 ;full LMARGN = 2 ;2 CHARS PARITY = 0 ;NO PARITY device =-/} 1 ;R1: ELSE BACKS = GETD(3) BAUD = GETD(3) DEBUG = GETD(3) IMAGE = GETD(3) LOCALECHO = GETD(-0}3) LMARGN = GETD(3) PARITY = GETD(3) DEVICE = GETD(3) FI CLOSE(3) RETURN;SET PARAMETERSPROC Params() -1}BYTE cmd STRING ts DO Put(125) PRINTE("Parameters are:") IF BACKS = 8 THEN TS = "control-H" ELSE -2}TS = "rub out" FI PRINTF(" A - Back S sends (%S)%E", ts) ts = DecodeBaud(baud) PRINTF(" B - Baud rat-3}e (%S)%E", TS) ts = DecodeFlag(debug) PRINTF(" D - Debugging (%S)%E", ts) IF IMAGE = 0 THEN t-4}s = "text" ElSE ts = "binary" FI PRINTF(" F - File type (%S)%E", ts) ts = DecodeFlag(localecho)-5} PRINTF(" L - Local-Echo (%S)%E", ts) PRINTF(" M - Margin (%D)%E", LMARGN) IF PARITY = 0 THEN TS = -6}"none" ELSEIF PARITY = 1 THEN TS = "odd" ELSEIF PARITY = 2 THEN TS = "even" ELSEIF PARITY = 3 THEN -7} TS = "on" FI PRINTF(" P - Parity (%S)%E", ts) PRINTF(" R - RS-232C Device (R%D:)%E", device) PRIN-8}TE("^S - Save parameters") PRINTE("^R - Restore paramters") PRINTF(" Q - Quit (back to Commands)%E") PRINT-9}F("Parameter to change -> ") cmd = GetD(1) cmd = ToUpper(cmd) IF IsAlpha(cmd) <> 0 THEN Put(cmd) FI -:} IF CMD = 'A THEN ;BACK S IF BACKS = 8 THEN BACKS = 127 ELSE BACKS = 8 FI ELSEIF -;}cmd = 'B THEN ;Baud-rate baud ==+ 1 IF baud > 6 THEN baud = 0 FI ELSEIF cmd = 'D THEN ;Debug debug = 1-<}-debug ELSEIF cmd = 'Q THEN ;Quit PRINTF("uit%E") RETURN ELSEIF cmd = 'F THEN ;File type IMAGE = -=}1-IMAGE ELSEIF cmd = 'L THEN ;local-echo localecho = 1 - localecho ELSEIF CMD = 'M THEN ;Margin IF LMAR->}GN < 2 THEN LMARGN ==+ 1 ELSE LMARGN = 0 FI ELSEIF CMD = 'P THEN ;PARITY IF PARITY < 3-?} THEN PARITY ==+ 1 ELSE PARITY = 0 FI ELSEIF cmd = 'R THEN ;RS-232C device ==+ 1 -@} IF device > 4 THEN device = 1 FI ELSEIF cmd = 'S-'@ THEN ;Save Parameters PRINTE("Saveing") SAVEPARAMS() -A} ELSEIF cmd = 'R-'@ THEN ;Restore parameters PRINTE("Restoring") RESTOREPARAMS() FI ODBYTE FUNC Menu(B-B}YTE FLAG) BYTE cmd DO IF FLAG = 1 THEN PUT(125) FI PRINTF("%E%ECommands are:%E") PRINTE(" A - Auto-C}-dial (then connect)") PRINTE(" C - Connect (to remote computer)") PRINTE(" D - Micro-DOS") PRINTE(" F - Finish (-D}remote server mode)") PRINTE(" P - Parameters (inspect and change)") PRINTE(" R - Receive (a file)") PRINTE(" S --E} Send (a file)") PRINTF(" Q - Quit (back to DOS)%E%E") PRINTF("Command -> ") DO cmd = GetD(1) cmd = T-F}oUpper(cmd) UNTIL INSET(CMD, "ACDFPRSQ") <> 0 OD Put(cmd) IF CMD = 'A THEN ;Auto-dial PRINTE("uto-dial-G}") IF AutoDial() = 1 THEN RETURN(1) FI ELSEIF cmd = 'C THEN ;connect PRINTE("onnect") -H} RETURN(1) ELSEIF cmd = 'F THEN ;Finish PRINTE("inish") Finish() ELSEIF cmd = 'D THEN ;MICRO-DOS -I} PRINTE("os") MICRODOS() ELSEIF cmd = 'Q THEN ;Quit PRINTF("uit%E") RETURN(0) ELSEIF cmd = 'P T-J}HEN ;Parameters PRINTF("arameters%E") Params() ELSEIF cmd = 'S THEN ;Send PRINTE("end") SENDSW()-K} ELSEIF cmd = 'R THEN ;Recieve PRINTE("ecieve") RECSW() FI ODBYTE FUNC MainLoop() BYTE FLAG, I E-L}RROR = MERROR ;SETUP MY ERROR ROUTINE EOL = CR QUOTE = MYQUOTE PAD = 0 PADCHAR = 0 ESCCHR = BRKCHR HOST = -M}FALSE PutD(0, 125) PRINTE("Kermit for the Atari Home Computer") PRINTE(" and the ATARI 850, with Hayes") PRINTE(" -N}Smartmodem auto-dial support.") PRINTE("v1.1 (c) 1983 John Howard Palevich") PRINTE("- Feel free to copy this program -")-O} FOR I = 1 TO 7 DO CLOSE(I) OD ERRORNUM = 0 OPEN(1, "R:", 8, 0) IF ERRORNUM >= 128 THEN PRINTF("Can't ope-P}n R: -- error %D%E", ERRORNUM) RETURN(0) FI Close(1) RestoreParams() ERRORNUM = 0 Open(1, "K:", 4, 0) -Q}IF ERRORNUM >= 128 THEN PRINTF("Can't open K: -- error %D%E", ERRORNUM) RETURN(0) FI FLAG = 0 WHILE Menu-R}(FLAG) = 1 DO TTYMode() OD Close(1) RETURN(1)PROC MAIN() IF MainLoop() = 0 THEN PUTE() PRINTE("Type a-S}ny key to exit") WHILE CH = $FF DO OD CH = $FF FI RETURN;--- END OF D:KMAIN.ACT --- PUTE() PRINTE("Type a,b;D:KMENU.ACT; Menu functions of Kermit programMODULE DEFINE NUMWID = "38" STRING PNFILE = "D:KERMIT.PNS" STRING PAR1U}AMFILE = "D:KERMIT.OPT";Restore Phone Number BufferPROC RESTNUMS() BYTE I, J Close(3) ERRORNUM = 0 OPEN(3, PNFIL1V}E, 4, 0) IF ERRORNUM < 128 THEN FOR I = 0 TO 19 DO ERRORNUM = 0 InputMD(3,SBUF+I*NUMWID, 37) IF ERROR1W}NUM >= 128 THEN EXIT FI OD ELSE I = 0 ;Couldn't find file FI CLOSE(3) FOR J = I TO 19 DO 1X} SBUF(NUMWID*J) = 0 OD RETURN;Display the editor screenPROC DispES() BYTE I ;Display Screen CRSINH = 1 PUT(11Y}25) PRINTE("Computer Name (baud rate) # 555-1212") FOR I = 0 TO 19 DO Put(32) PRINTE(SBUF+NUMWID*I) OD Pr1Z}intE("Use arrows, then RETURN to dial,") PrintE("or ESC to quit. ^S Saves") PRINT("SPACE modifies, ^R Restores") Positi1[}on(LMARGN, 0) Put($1F) CRSINH = 0 Put($1E) RETURN;Auto-Dial a number, return 1 if;successful, 0 if failure;; Als1\}o has provisions for editing; phone numbers.BYTE FUNC EditDial() BYTE I, NN, C, CY BYTE POINTER P RESTNUMS() DISP1]}ES() CY = 0 ;Edit/Select Loop DO CRSINH = 1 POSITION(LMARGN, CY+1) PUT(27) PUT($1F) C = GetD(1)1^} IF C = 32 THEN ;User wants to change this line POSITION(LMARGN,CY+1) CRSINH = 0 PUT('?) Inpu1_}tMD(0,SBUF+CY*NUMWID, 37) DISPES() ELSEIF C = 27 THEN Position(LMARGN, 23) CRSINH = 0 PUT($9C) 1`} PrintE("Not Dialing") RETURN(0) ELSEIF (C = $1C OR C = '-) AND CY > 0 THEN PUT($7E) ;Erase the ar1a}row CY ==- 1 ELSEIF (C = $1D OR C = '=) AND CY < 19 THEN PUT($7E) ;Erase the arrow CY ==+ 1 1b} ELSEIF C = 'S-'@ THEN ;^S OPEN(3, PNFILE, 8, 0) FOR I = 0 TO 19 DO P = SBUF+I*NUMWID IF P(0) > 01c} THEN PRINTDE(3, P) FI OD CLOSE(3) RESTNUMS() DISPES() ;Just to inform user C1d}Y = 0 ELSEIF C = 'R-'@ THEN ;^R RESTNUMS() DISPES() CY = 0 ELSEIF C = $9B THEN ;RETURN EXIT1e} FI OD ;Dial the chosen number CRSINH = 0 PUT(125) P = SBUF+CY*NUMWID PrintE(P) C = AutoDial(P) RETURN(1f}C);Execute a DOS-type commandPROC DODOS(BYTE CMD STRING FSPEC) STRING FMSCOM = [0 $21 $23 $24 $FE] STRING 1g}FILNAM(21) BYTE I, CNF IF FSPEC(0) = 0 AND CMD <> 'A THEN RETURN FI IF CMD = 'A THEN ;DIRECTORY IF FSPE1q}B%DOS SYSB*)DUP SYSBS00READMETXTBUKCOM1030ACTB$jKCOM850 ACTB'KDIAL ACTB KERMIT ACTBKERMIT DOCBKERMIT PNSB0KFUNC ACTBKIO ACTB9KMAIN ACTBMTKMENU ACTBKKPRO ACTB(KTTY ACTC(0) = 0 THEN STRCPY(FSPEC, "D#:*.*") FSPEC(2) = '0 + DISKN FI NORMALIZE(FSPEC) CLOSE(6) ERRORNU1r}M = 0 OPEN(6, FSPEC, 6, 0) DO INPUTMD(6, FILNAM, 20) IF ERRORNUM >= 128 THEN EXIT FI PRINTE(FILNAM)1s} IF FILNAM(1) >= '0 AND FILNAM(1) <= '9 THEN EXIT FI OD CLOSE(6) ELSE ;ALL OTHER COMM1t}ANDS NORMALIZE(FSPEC) I = INSET(CMD, "DFGI") IF I = 0 THEN RETURN FI IF CMD = 'I THEN PRINTF("Type 1u}'Y' to format %S%E", FSPEC) CNF = GetD(1) IF TOUPPER(CNF) <> 'Y THEN PRINTF("Aborted%E") 1v} RETURN ELSE PRINT("Formatting. . .") FI FI ERRORNUM = 0 XIO(6, 0, FMSCOM(I), 0, 0, FSPE1w}C) IF ERRORNUM >= 128 THEN PRINTF("Disk I/O error %B%E", ERRORNUM) FI FI RETURN PROC MICRO1x}DOS() BYTE cmd STRING fspec(21) PUT(125) DO PRINTE("Micro-DOS:") PRINTE(" A - Disk Directory") PRINTE(" D1y} - Delete File") PRINTE(" F - Lock File") PRINTE(" G - Unlock File") PRINTE(" I - Format Diskette") PRINTE(" 1z}Q - Quit (back to main menu)") PRINTF("%ECommand -> ") DO cmd = GetD(1) cmd = ToUpper(cmd) UNTIL 1{} INSET(CMD, "ADFGIQ") > 0 OD PUT(CMD) IF cmd = 'Q THEN PUTE() RETURN FI PRINTF("%EFile 1|}spec -> ") InputMD(0, fspec, 20) DoDos(cmd, fspec) OD; SAVE PARAMETERSPROC SaveParams() ERRORNUM = 0 OPEN(31}}, PARAMFILE, 8, 0) IF ERRORNUM < 128 THEN ;Can write PUTD(3, BACKS) PUTD(3, BAUD) PUTD(3, DISKN) 1~}PUTD(3, DEBUG) PUTD(3, IMAGE) PUTD(3, LOCALECHO) PUTD(3, LMARGN) PUTD(3, PARITY) PUTD(3, DNUM) PUTD(31}, dial) FI CLOSE(3) RETURN;RESTORE PARAMETERSPROC RestoreParams() CARD TEMP CLOSE(3) ERRORNUM = 0 OPEN(3, 1}PARAMFILE, 4, 0) IF ERRORNUM >= 128 THEN ;Defaults PRINTF("Couldn't open %S; error %D%E", PARAMFILE, ER1}RORNUM) BACKS = 127 ;RUB OUT baud = 0 ;300 baud DISKN = 1 ;D1: debug = 0 1} ;debug off IMAGE = 0 ;TEXT localecho = 0 ;full LMARGN = 2 ;2 CHARS PARITY 1}= 0 ;NO PARITY DNUM = 1 ;PORT 1 dial = 0 ;Pulse ELSE BACKS = GETD(3) BAUD1} = GETD(3) DISKN = GETD(3) DEBUG = GETD(3) IMAGE = GETD(3) LOCALECHO = GETD(3) LMARGN = GETD(3) PARIT1}Y = GETD(3) DNUM = GETD(3) DIAL = GETD(3) FI CLOSE(3) RETURN;SET PARAMETERSPROC Params() BYTE cmd STRIN1}G ts DO Put(125) PRINTE("Parameters are:") IF BACKS = 8 THEN TS = "control-H" ELSE TS = "rub out" 1} FI PRINTF(" A - Back S sends (%S)%E", ts) ts = DecodeBaud(baud) PRINTF(" B - Baud rate (%S)%E", 1} TS) IF IMAGE = 0 THEN ts = "text" ElSE ts = "binary" FI PRINTF(" D - Default disk drive (D%D:)1}%E", diskn) PRINTF(" F - File type (%S)%E", ts) PRINTF(" I - I/O Port (%D)%E", DNUM) IF dial1} = 0 THEN ts = "pulse" ELSE ts = "tone" FI PRINTF(" T - Dialing method (%S)%E", ts) ts = D1}ecodeFlag(localecho) PRINTF(" L - Local-Echo (%S)%E", ts) PRINTF(" M - Margin (%D)%E", LMARGN) IF PARITY1} = 0 THEN TS = "none" ELSEIF PARITY = 1 THEN TS = "odd" ELSEIF PARITY = 2 THEN TS = "even" ELSE1}IF PARITY = 3 THEN TS = "on" FI PRINTF(" P - Parity (%S)%E", ts) PRINTE("^S - Save parameters") PRINTE1}("^R - Restore paramters") ts = DecodeFlag(debug) PRINTF(" * - Debug Mode (%S)%E", ts) PRINTF(" Q - 1}Quit (back to Commands)%E") PRINTF("Parameter to change -> ") cmd = GetD(1) cmd = ToUpper(cmd) IF IsAlpha(cm1}d) <> 0 THEN Put(cmd) FI IF CMD = 'A THEN ;BACK S IF BACKS = 8 THEN BACKS = 127 ELSE 1} BACKS = 8 FI ELSEIF cmd = 'B THEN ;Baud-rate baud ==+ 1 IF baud > 6 THEN baud = 0 FI ELSEI1}F cmd = 'D THEN ;Disk number diskn ==+ 1 IF diskn > 4 THEN diskn = 1 FI ELSEIF cmd = '* THEN ;Debug de1}bug = 1-debug ELSEIF cmd = 'Q THEN ;Quit PRINTF("uit%E") RETURN ELSEIF cmd = 'F THEN ;File type I1}MAGE = 1-IMAGE ELSEIF cmd = 'L THEN ;local-echo localecho ==+ 1 IF localecho > 1 THEN LOCALECHO = 01} FI ELSEIF cmd = 'T THEN ;dialing DIAL ==+ 1 IF DIAL > 1 THEN DIAL = 0 FI ELSEIF CMD1} = 'M THEN ;Margin LMARGN ==+ 1 IF LMARGN > 2 THEN LMARGN = 0 FI ELSEIF CMD = 'P THEN ;PARITY1} PARITY ==+ 1 IF PARITY > 3 THEN PARITY = 0 FI ELSEIF cmd = 'I THEN ;Port # dnum ==+ 1 1} IF dnum > 4 THEN dnum = 1 FI ELSEIF cmd = 'S-'@ THEN ;Save Parameters PRINTE("Saving") SAVEPARAMS() 1} ELSEIF cmd = 'R-'@ THEN ;Restore parameters PRINTE("Restoring") RESTOREPARAMS() ELSE PUT(253) FI1} ODPROC Main() BYTE cmd, FLAG, I, BANK = $D500 BANK = 0 ;SETUP MY ERROR ROUTINE ERROR = MERROR EOL = CR QUO1}TE = MYQUOTE PAD = 0 PADCHAR = 0 HOST = FALSE FOR I = 1 TO 7 DO CLOSE(I) OD PRINTE("Kermit for the Atari Ho1}me Computer") PRINTE("v1.2 (c) 1984 John Howard Palevich") MODEMINIT() PRINTE("- Feel free to copy this program -") 1}RestoreParams() Open(1, "K:", 4, 0) IF OPENR() <> 0 THEN PRINTE("PRESS ANY KEY TO EXIT") CH = $FF WHILE CH = 1}$FF DO OD CH = $FF ELSE STOPR() DO PRINTF("%E%ECommands are:%E") PRINTE(" A - Auto-dial (then conn1}ect)") PRINTE(" C - Connect (to remote computer)") PRINTE(" D - Micro-DOS") PRINTE(" F - Finish (remote ser1}ver mode)") PRINTE(" H - Hang up (the phone)") PRINTE(" P - Parameters (inspect and change)") PRINTE(" R - 1}Receive (a file)") PRINTE(" S - Send (a file)") PRINTF(" Q - Quit (back to DOS)%E%E") PRINTF("Command -> ")1} DO cmd = GetD(1) cmd = ToUpper(cmd) UNTIL INSET(CMD, "ACDFHPRSQ") <> 0 OD Put(cmd)1} IF CMD = 'A THEN ;Auto-dial PRINTE("uto-dial") IF EditDial() = 1 THEN TTYMODE() 1} FI ELSEIF cmd = 'C THEN ;connect PRINTE("onnect") TTYMODE() ELSEIF cmd = 'F THEN ;Fini1}sh PRINTE("inish") Finish() ELSEIF cmd = 'H THEN ;Hang up the phone PRINTE("ang up") 1} HangUp() ELSEIF cmd = 'D THEN ;MICRO-DOS PRINTE("os") MICRODOS() ELSEIF cmd = 'Q THEN ;Q1}uit PRINTE("uit") EXIT ELSEIF cmd = 'P THEN ;Parameters PRINTE("arameters") Params()1} ELSEIF cmd = 'S THEN ;Send PRINTE("end") SENDSW() ELSEIF cmd = 'R THEN ;Recieve PRINTE("1}ecieve") RECSW() FI OD CLOSER() FI CLOSE(1) RETURN;--- END OF D:KMENU.ACT --- PRINTE("0n;D:KPRO.ACT; KERMIT protocol section; RInit();; Receive InitializationBYTE FUNC RINIT(STRING FSPEC) INT LEN, NUM, T5} IF DEBUG = 1 THEN PRINTE("RInit") FI NUMTRY ==+ 1 IF NUMTRY > MAXTRY THEN RETURN('A) FI IF FSPEC(0) > 05} THEN FOR T = 1 TO FSPEC(0) DO PACKET(T-1) = FSPEC(T) OD SPACK('R, 0, T-1, PACKET) FI T = RPACK(@L5}EN, @NUM, PACKET) IF T = 'S THEN RPAR(PACKET) SPAR(PACKET) SPACK('Y, N, 6, PACKET) OLDTRY = NUMTRY NUMT5}RY = 0 N = (N + 1) MOD 64 RETURN('F) ELSEIF T = FALSE THEN RETURN(STATE) ELSE RETURN('A) FI; RFile();; Rec5}eive File HeaderBYTE FUNC RFile() INT LEN, NUM, T BYTE W IF DEBUG = 1 THEN PRINTF("RFile%E") FI NUMTRY ==+ 15} IF NUMTRY > MAXTRY THEN RETURN('A) FI T = RPACK(@LEN, @NUM, PACKET+1) PACKET(0) = LEN IF T = 'S THEN OLDT5}RY ==+ 1 IF OLDTRY > MAXTRY THEN RETURN('A) FI IF (N = 0 AND NUM = 63) OR (N <> 0 AND NUM = N-1) THEN 5} SPACK('Y, NUM, 0, 0) NUMTRY = 0 RETURN(STATE) ELSE RETURN('A) FI ELSEIF T = 'F THEN IF NUM 5}<> N THEN RETURN('A) FI STOPR() NORMALIZE(PACKET) ERRORNUM = 0 OPEN(3, PACKET, 8, 0) STARTR() IF ERRO5}RNUM >= 128 THEN PRINTF("Couldn't create %S; error %D%E", PACKET, ERRORNUM) RETURN('A) FI PRI5}NTF("Receiving %S%E", PACKET) SPACK('Y, N, 0, 0) OLDTRY = NUMTRY NUMTRY = 0 N = (N+1) MOD 64 RETURN5}('D) ELSEIF T = 'B THEN IF NUM <> N THEN RETURN('A) FI SPACK('Y, N, 0, 0) ;WAIT 1 SECOND FOR ACK TO DRAIN 5}W = RTCLOCK+60 WHILE W <> RTCLOCK DO OD RETURN('C) ELSEIF T = FALSE THEN RETURN(STATE) ELSE RETURN('A) FI; R5}Data();; Receive DataBYTE FUNC RData() INT NUM, LEN, T IF DEBUG = 1 THEN PRINTF("RData%E") FI NUMTRY ==+ 1 5} IF NUMTRY > MAXTRY THEN RETURN('A) FI T = RPACK(@LEN, @NUM, PACKET) IF T = 'D THEN IF NUM <> N THEN 5} OLDTRY ==+ 1 IF OLDTRY > MAXTRY THEN RETURN('A) FI IF (N = 0 AND NUM = 63) OR (N <> 0 AND NUM = N-1) 5} THEN SPACK('Y, NUM, 0, 0) NUMTRY = 0 RETURN(STATE) ELSE RETURN('A) FI FI5} BUFEMP(PACKET, LEN) SPACK('Y, N, 0, 0) OLDTRY = NUMTRY NUMTRY = 0 N = (N+1) MOD 64 RETURN('D) ELSE5}IF T = 'F THEN OLDTRY ==+ 1 IF OLDTRY > MAXTRY THEN RETURN('A) FI IF (N = 0 AND NUM = 63) OR (N <5}> 0 AND NUM = N-1) THEN SPACK('Y, NUM, 0, 0) NUMTRY = 0 RETURN(STATE) ELSE RETURN('A) FI5} ELSEIF T = 'Z THEN IF NUM <> N THEN RETURN('A) FI IF DEBUG = 1 THEN PRINTE("End-of-File") FI STOPR()5} CLOSE(3) STARTR() SPACK('Y, N, 0, 0) N = (N+1) MOD 64 RETURN('F) ELSEIF T = FALSE THEN RETURN(STATE)5} ELSE RETURN('A) FI ; RecSw();; This is the state table switcher; for receiving filesPROC RECSW() STRING FSPEC5}(20) INT NUM, LEN, T STARTR() PUT(125) PRINTE("Type the file to receive, or just") PRINTE("RETURN if the other com5}puter is not") PRINTE("in Server mode.") PUTE() PRINT("File Spec -> ") INPUTMD(0, FSPEC, 19) PRINTE("Receiving Fil5}e(s)") PRINTE("type any key to abort") STATE = 'R N = 0 NUMTRY = 0 DO IF CH <> 255 THEN PRINTE("User Abo5}rting") CH = 255 EXIT FI IF STATE = 'D THEN STATE = RDATA() ELSEIF STATE = 'F THEN STATE = RFILE() 5} ELSEIF STATE = 'R THEN STATE = RINIT(FSPEC) ELSEIF STATE = 'A THEN PRINTE("Aborting") EXIT ELSE E5}XIT FI OD STOPR() Close(3) RETURN; SInit;; Send Initiate:; Send my parameters, get other; side's backBY5}TE FUNC SINIT() INT NUM, LEN BYTE T IF DEBUG <> 0 THEN PRINTF("SInit%E") FI NUMTRY ==+ 1 IF NUMTRY > MAXTRY5} THEN RETURN('A) FI SPAR(PACKET) IF DEBUG <> 0 THEN PRINTF("n = %D%E", N) FI ;Clear out any junk in the inp5}ut ;buffer WHILE NCIB() > 0 DO GETD(2) OD SPACK('S, N, 6, PACKET) T = RPACK(@LEN, @NUM, RECPKT) IF T = 'N THEN5} RETURN(STATE) ELSEIF T = 'Y THEN IF N <> NUM THEN RETURN(STATE) FI RPAR(RECPKT) IF EOL = 0 THEN 5} EOL = 13 FI IF QUOTE = 0 THEN QUOTE = '# FI NUMTRY = 0 N = (N + 1) MOD 64 IF FILNAM = 0 THEN5} RETURN('A) FI ;Open a file STOPR() ERRORNUM = 0 Close(3) OPEN(3, FILNAM, 4, 0) STARTR() 5} IF ERRORNUM >= 128 THEN PRINTF("Error %D; couldn't read %S", ERRORNUM, FILNAM) RETURN('A) FI PRI5}NTF("Sending %S%E", FILNAM) RETURN('F) ELSEIF T = FALSE THEN RETURN(STATE) ELSE RETURN('A) FI ; SFile;; Send 5}File HeaderBYTE FUNC SFILE() INT NUM, LEN, T, I STRING STFNAME(20) IF DEBUG = 1 THEN PRINTE("SFile") FI NUMT5}RY ==+ 1 IF NUMTRY > MAXTRY THEN RETURN('A) FI I = 1 ;STANDARD FILE NAMES DON'T HAVE D1: WHILE FILNAM(I) <> ': 5}DO I ==+ 1 OD LEN = FILNAM(0)-I FOR T = 0 TO LEN-1 DO STFNAME(T) = FILNAM(I+T+1) OD SPACK('F, N, LEN, STFNAME) 5} T = RPACK(@LEN, @NUM, RECPKT) IF T = 'N OR T = 'Y THEN IF T = 'N THEN NUM ==- 1 IF NUM < 0 THEN NUM = 5}63 FI FI IF N <> NUM THEN RETURN(STATE) FI NUMTRY = 0 N = (N + 1) MOD 64 SIZE = BUFILL(PAC5}KET) IF SIZE = EOF THEN RETURN('Z) ELSE RETURN('D) FI ELSEIF T = FALSE THEN RETURN(STATE) ELSE RE5}TURN('A) FI; SData;; Send File DataBYTE FUNC SData() INT NUM, LEN, T NUMTRY ==+ 1 IF NUMTRY > MAXTRY THEN 5}RETURN('A) FI SPACK('D, N, SIZE, PACKET) T = RPACK(@LEN, @NUM, RECPKT) IF T = 'N OR T = 'Y THEN IF T = 'N THE5}N NUM ==- 1 IF NUM < 0 THEN NUM = 63 FI FI IF N <> NUM THEN RETURN(STATE) FI NUMTRY = 5}0 N = (N + 1) MOD 64 SIZE = BUFILL(PACKET) IF SIZE = EOF THEN RETURN('Z) FI RETURN('D) ELSEIF T =5} FALSE THEN RETURN(STATE) ELSE RETURN('A) FI; SEOF();; Send End-Of-FileBYTE FUNC SEOF() INT NUM, LEN, T IF5} DEBUG = 1 THEN PRINTF("SEOF%E") FI NUMTRY ==+ 1 IF NUMTRY > MAXTRY THEN RETURN('A) FI SPACK('Z, N, 0, PAC5}KET) IF DEBUG = 1 THEN PRINT("SEOF1 ") FI T = RPACK(@LEN, @NUM, RECPKT) IF T = 'N OR T = 'Y THEN IF T = 'N5} THEN NUM ==- 1 IF NUM < 0 THEN NUM = 63 FI IF N <> NUM THEN RETURN(STATE) FI FI IF DEBUG = 1 T5}HEN PRINTF("SEOF2 ") FI IF N <> NUM THEN RETURN(STATE) FI NUMTRY = 0 N = (N + 1) MOD 64 5} IF DEBUG = 1 THEN PRINTF("Closing %S%E", FILNAM) FI STOPR() IF DEBUG = 1 THEN PRINTF("getting next5} file%E") FI DO FILNAM = GETNEXT(6) IF FILNAM = 0 THEN EXIT FI CLOSE(3) ERRORNUM = 0 OP5}EN(3,FILNAM, 4, 0) IF ERRORNUM < 128 THEN EXIT ELSE PRINTF("Can't read %S; Error %D%E", 5} FILNAM, ERRORNUM) FI OD STARTR() IF FILNAM = 0 THEN RETURN('B) FI PRINTE(FILNAM) 5}RETURN('F) ELSEIF T = FALSE THEN RETURN(STATE) ELSE RETURN('A) FI; SBreak();; Send Break (End-of-Text)BYTE FUNC S5}Break() INT NUM, LEN, T IF DEBUG = 1 THEN PRINTF("SBreak%E") FI NUMTRY ==+ 1 IF NUMTRY > MAXTRY THEN RETU5}RN('A) FI SPACK('B, N, 0, PACKET) T = RPACK(@LEN, @NUM, RECPKT) IF T = 'N OR T = 'Y THEN IF T = 'N THEN 5} NUM ==- 1 IF NUM < 0 THEN NUM = 63 FI IF N <> NUM THEN RETURN(STATE) FI FI IF N <> NUM 5} THEN RETURN(STATE) FI NUMTRY = 0 N = (N + 1) MOD 64 RETURN('C) ELSEIF T = FALSE THEN RETURN(STAT5}E) ELSE RETURN('A) FI;MAIN SEND FILE ROUTINEPROC SENDSW() STRING FSpec(20) DO Print("File spec -> ") INPU5}TMD(0, FSPEC, 19) IF FSPEC(0) = 0 THEN RETURN FI Normalize(FSPEC) FILNAM = GETFIRST(6, FSPEC) IF FILNAM = 0 T5}HEN PRINTE("Invalid file name") FI UNTIL FILNAM <> 0 OD Put(125) PRINTF("Sending %S%E", FSpec) PRINTE5}("Type any key to abort.") STARTR() STATE = 'S N = 0 NUMTRY = 0 DO IF CH <> 255 THEN PRINTE("User Abort"5}) CH = 255 EXIT FI IF STATE = 'D THEN STATE = SDATA() ELSEIF STATE = 'F THEN STATE = SFILE() 5}ELSEIF STATE = 'Z THEN STATE = SEOF() ELSEIF STATE = 'S THEN STATE = SINIT() ELSEIF STATE = 'B THEN STATE = SBREAK()5} ELSEIF STATE = 'A THEN PRINTE("Aborting") EXIT ELSE EXIT FI OD STOPR() CLOSE(3) RETURN;Tell5} Server to quitPROC Finish() INT NUM, LEN, T IF DEBUG = 1 THEN PRINTE("Finish") FI STARTR() FOR NUMTRY = 0 T5}O 3 DO PACKET(0) = 'F SPACK('G, 0, 1, PACKET) T = RPACK(@LEN, @NUM, RECPKT) IF T = 'N OR T = 'Y THEN 5} IF T = 'N THEN NUM ==- 1 IF NUM < 0 THEN NUM = 63 FI IF 0 <> NUM THEN EXIT F5}I FI IF 0 = NUM THEN STOPR() RETURN FI FI OD STOPR() PRINTE("Server didn'5}t respond") RETURN ;--------------------------;Kermit Protocol code ends here;--------------------------; --- END OF 5}D:KPRO.ACT ---ETURN ;--------------------------;Kermit Protocol code ends here;--------------------------; --- END OF 4;D:KTTY.ACT; Terminal emulation for the masses; Emulates a VT-52, Option quits,; Start scrolls.MODULE CARD ARRAY LBASE9}(24) BYTE ARRAY LCUR(24) BYTE CX, CY, LMAR, DLTOGGLE,TSTATE, consol = $D01F CARD SDLST = $230, SAVEDL, H9}ELPLINE;Create a display list and display it;; Uses: LBASE, LCUR, LMAR, SAVEDL,; Modifies: DLTOGGLE, SCREEN MEMORYPROC9} HACKDISPLAY() BYTE ARRAY DBASE BYTE I CARD J, TBASE DBASE = DLTOGGLE*85+SAVEDL+72 DLTOGGLE = 1 - DLTOGGLE TBASE 9}= DBASE FOR I = 0 TO 2 DO DBASE(I) = $70 OD FOR I = 0 TO 23 DO DBASE ==+ 3 DBASE(0) = $42 J = LCUR(I) 9} J = LBASE(J) + LMAR - LMARGN DBASE(1) = J DBASE(2) = J RSH 8 OD DBASE(3) = $00 DBASE(4) = $42 DBASE(5) = H9}ELPLINE DBASE(6) = HELPLINE RSH 8 DBASE(7) = $41 DBASE(8) = TBASE DBASE(9) = TBASE RSH 8 SDLST = TBASE RETURNPR9}OC CFLIP() BYTE POINTER M BYTE I I = LCUR(CY) M = LBASE(I) + CX M^ ==! $80 RETURNPROC LCLEAR(BYTE LINE) BYTE 9}I BYTE ARRAY T I = LCUR(LINE) T = LBASE(I)-2 FOR I = 0 TO 81 DO T(I) = 0 OD RETURNPROC TINIT() CARD I, J9} ;First, find 24 valid lines in ;Sbuf. Valid lines don't cross 4K J = SBUF FOR I = 0 TO 23 DO IF (J RSH 12) <>9} ((J + 81) RSH 12) THEN J = (J & $F000) + $1000 FI LBASE(I) = J+2 J ==+ 82 LCUR(I) = I ;set :}up current line order LCLEAR(I) OD ;Now set up a display list SAVEDL = SDLST HELPLINE = SDLST+32 PUT(125) PRI:}NTE("OPTION quits, (SHIFT)+START scrolls") DLTOGGLE = 0 TSTATE = 'N CX = 0 CY = 0 LMAR = 0 CFLIP() HACKDISPLAY(:}) RETURNBYTE FUNC TPUTN(BYTE C) BYTE I, TEMP BYTE POINTER M BYTE ARRAY TOSCR = [$40 $00 $20 $60] CFLIP() IF C <:} 32 THEN IF C = 27 THEN RETURN('E) ELSEIF C = 10 THEN IF CY < 23 THEN CY ==+ 1 ELSE :} LCLEAR(0) TEMP = LCUR(0) FOR I = 0 TO 22 DO LCUR(I) = LCUR(I+1) OD LCUR(23:}) = TEMP HACKDISPLAY() FI ELSEIF C = 13 THEN CX = 0 ELSEIF C = 7 THEN ;BELL SETCOLOR(:}4, 0, 14) I = RTCLOCK + 2 WHILE I <> RTCLOCK DO OD SETCOLOR(4, 0, 0) ELSEIF C = 8 THEN ;BACKSPACE:} IF CX > 0 THEN CX ==- 1 FI ELSEIF C = 9 THEN ;TAB IF CX < 72 THEN CX = (CX + 8) :}& $F8 FI ELSEIF C = 12 THEN FOR I = 0 TO 23 DO LCLEAR(I) OD CX = 0 CY = 0: } FI ELSE ;printing char I = LCUR(CY) M = LBASE(I) + CX M^ = TOSCR((C & $60) RSH 5) % (C & $9F: }) IF CX < 79 THEN CX ==+ 1 FI FI CFLIP() RETURN('N)BYTE FUNC TPUTE(BYTE C) BYTE TEMP, I BYTE ARRAY M IF: } C = 'A THEN IF CY > 0 THEN CY ==- 1 FI ELSEIF C = 'B THEN IF CY < 23 THEN CY ==+ 1 FI ELSE: }IF C = 'C THEN IF CX < 79 THEN CX ==+ 1 FI ELSEIF C = 'D THEN IF CX > 0 THEN CX ==- 1 FI EL: }SEIF C = 'H THEN CX = 0 CY = 0 ELSEIF C = 'I THEN IF CY > 0 THEN CY ==- 1 ELSE LCLEAR(23) :} TEMP = LCUR(23) FOR I = 0 TO 22 DO LCUR(23-I) = LCUR(22-I) OD LCUR(0) = TEMP HACKDISPLAY():} FI ELSEIF C = 'J OR C = 'K THEN I = LCUR(CY) M = LBASE(I) FOR I = CX TO 79 DO M(I) = 0 OD IF:} C = 'J THEN FOR I = CY+1 TO 23 DO LCLEAR(I) OD FI ELSEIF C = 'Y THEN RETURN('R) ELSEIF C = ':}Z THEN PUTD(2, 27) PUTD(2, '/) PUTD(2, 'Z) FI CFLIP() RETURN('N)PROC TPUTSW(BYTE C) IF TSTATE = 'N THEN:} TSTATE = TPUTN(C) ELSEIF TSTATE = 'E THEN TSTATE = TPUTE(C) ELSEIF TSTATE = 'R THEN IF C < 32 THEN C = 32 FI:} CY = C - 32 IF CY > 23 THEN CY = 23 FI TSTATE = 'C ELSEIF TSTATE = 'C THEN IF C < 32 THEN C = 32 FI CX:} = C - 32 IF CX > 79 THEN CX = 79 FI CFLIP() TSTATE = 'N ELSE TSTATE = 'N FI RETURNPROC TQUIT() :} SDLST = SAVEDL PUT(125) RETURNPROC TTYMode() BYTE c, SKSTAT = $D20F, OLDSCROLL StartR() TINIT() OLDSCROLL = :}RTCLOCK - 1 DO IF ch <> $FF THEN c = GetD(1) IF c = 155 THEN c = 13 ELSEIF c = 127 THEN c = 9 E:}LSEIF c = $7E THEN c = backs FI PutD(2, c) IF localecho = 1 THEN TPUTSW(c) FI FI IF :}ncib() > 0 THEN c = GetD(2) & $7F ;strip parity TPUTSW(c) FI consol = 8 IF (consol & 4) = 0 THEN :} EXIT ELSEIF (CONSOL & 1) = 0 AND RTCLOCK <> OLDSCROLL THEN ;START - SHIFT LEFT & RIGHT IF (SKSTAT &:} 8) = 0 THEN IF LMAR > 0 THEN LMAR ==- 1 FI ELSE IF LMAR < 40+LMARGN THEN L:}MAR ==+ 1 FI FI HACKDISPLAY() OLDSCROLL = RTCLOCK FI OD TQUIT() StopR() RETURN;End of:} D:KTTY.ACT FI FI HACKDISPLAY() OLDSCROLL = RTCLOCK FI OD TQUIT() StopR() RETURN;End of8